﻿using Player;
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private PlayerBody Player;

    private PlayerStateMachine<PlayerState> stateMachine;

    private PlayerState lastState;
    private PlayerState currentState;

    private float rollTimer;

    Vector2 lastDir;

    private void Start()
    {
        if (Player == null)
            Player = transform.GetComponent<PlayerBody>();

        if (stateMachine == null)
            stateMachine = new PlayerStateMachine<PlayerState>();

        stateMachine.AddState(PlayerState.Normal, new PlayerNormal(Player));
        stateMachine.AddState(PlayerState.Roll, new PlayerRoll(Player));

        currentState = PlayerState.Normal;
        stateMachine.ChangeState(currentState);
    }

    private void Update()
    {
        rollTimer += Time.deltaTime * Player.PlayerData.TimeScale;

        Vector2 dir = Vector2.zero;
        dir.x = InputRead.GetID(Player.ID).HorizontalRaw;
        dir.y = InputRead.GetID(Player.ID).VerticalRaw;
        dir.Normalize();
         
        if (InputRead.GetID(Player.ID).Roll)
            ReadyToRoll();

        switch (currentState)
        {
            case PlayerState.Normal:
                stateMachine.OnUpdate(dir);
                if (dir.magnitude != 0)
                    lastDir = dir;
                break;
            case PlayerState.Roll:
                stateMachine.OnUpdate(lastDir);
                CheckRollEnd();
                break;
            default:
                break;
        }

        if (InputRead.GetID(Player.ID).AttackNormalStart)
            ReadyAttack();
        else if(InputRead.GetID(Player.ID).AttackNormalEnd)
            AttackEnd();

    }

    private void FixedUpdate()
    {
          stateMachine.FixedUpdate();
    }

    private void ReadyAttack()
    {
        if (Player.PlayerStatus.isRoll || Player.PlayerStatus.isDorpDown || Player.PlayerStatus.isDead)
            return;
        Player.playerWeapon.AttackStart();
    }

    private void AttackEnd()
    {
        Player.playerWeapon.AttackEnd();
    }

    private void ReadyToMove()
    {
        if (currentState == PlayerState.Normal)
            return;
 
        if (Player.PlayerStatus.isRoll||Player.PlayerStatus.isDorpDown||Player.PlayerStatus.isDead)
            return;
        currentState = PlayerState.Normal;
        stateMachine.ChangeState(PlayerState.Normal);
    }

    private void ReadyToRoll()
    {
        if (Player.PlayerStatus.isDorpDown || Player.PlayerStatus.isDead)
            return;
        if (rollTimer < Player.PlayerData.RollInterval)
            return;
        currentState = PlayerState.Roll;
        stateMachine.ChangeState(currentState); 
        rollTimer = 0;
    }

    private void CheckRollEnd()
    {
        if(Player.PlayerStatus.isRoll == false)
        {
            currentState = PlayerState.Normal;
            stateMachine.ChangeState(currentState);
        }           
    }
}
